﻿using System;
using MediatR;
using Casamiel.Domain.Response.MWeb;
using Casamiel.Domain.Response;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Net.Http;
using Microsoft.Extensions.Options;
using Casamiel.Common;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Casamiel.Domain.Entity;
using Casamiel.Domain;
using Casamiel.Common.Extensions;

namespace Casamiel.Application.Commands.Tmall
{
    /// <summary>
    /// 
    /// </summary>
    public sealed   class TmallGetAllStoresCommandHandler:BaseCommandHandler,IRequestHandler<TmallGetAllStoresCommand,BaseResult<List<StoreEntity>>>
    {
        private readonly IMbrStoreRepository _mbrStoreRepository;
        private readonly AMapConfig _aMapConfig;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="netICService"></param>
        /// <param name="httpClientFactory"></param>
        /// <param name="optionsSnapshot"></param>
        /// <param name="mbrStoreRepository"></param>
        public TmallGetAllStoresCommandHandler(INetICService netICService, IHttpClientFactory httpClientFactory, IOptionsSnapshot<CasamielSettings> optionsSnapshot,
            IMbrStoreRepository mbrStoreRepository, IOptionsSnapshot<AMapConfig> settings)
       : base(netICService, httpClientFactory, optionsSnapshot)
        {
            _mbrStoreRepository = mbrStoreRepository;
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }
            _aMapConfig = settings.Value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<BaseResult<List<StoreEntity>>> Handle(TmallGetAllStoresCommand request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            var en = DistanceHelper.FindNeighPosition(request.Lng, request.Lat, request.Distance);
            //if (lat <= 0)
            //{
            //    var storelist = await _mbrStoreRepository.GetStoreByNameAsync<ICasaMielSession>("", 1, 10);
            //    var list = storelist.Data;
            //    return Ok(new { code = 0, content = list });
            //}
            var list = await _mbrStoreRepository.GeRectRangeAsync<ICasaMielSession>(en.MinLat, en.MinLng, en.MaxLat, en.MaxLng).ConfigureAwait(false);
            for (int i = 0; i < list.Count; i++)
            {
                list[i].IsSend = false;
                list[i].Distance = DistanceHelper.GetDistance(request.Lat, request.Lng, list[i].Latitude, list[i].Longitude);// _commonService.MapService.GetGistance(a, new Map { lat=item.Latitude.ToDouble(0), lng=item.Longitude.ToDouble(0)});

                var distributionRadius = $"{list[i].DistributionRadius}".ToDouble(0);
                if (list[i].Distance <= distributionRadius / 1000)
                {
                    if (list[i].IsOpenSend > 0)
                    {
                        var _distance = await GetDistance(request.Lng, request.Lat, list[i].Longitude, list[i].Latitude).ConfigureAwait(false);
                        if (_distance <= distributionRadius)
                        {
                            list[i].IsSend = true;
                        }
                    }
                }
            }
            //foreach (var item in list)
            //{
            //    item.Distance = DistanceHelper.GetDistance(request.Lat, request.Lng, item.Latitude, item.Longitude);// _commonService.MapService.GetGistance(a, new Map { lat=item.Latitude.ToDouble(0), lng=item.Longitude.ToDouble(0)});
            //}
            return new BaseResult<List<StoreEntity>>(list, 0, "");
        }

        /// <summary>
        /// Gets the distance.
        /// </summary>
        /// <returns>The distance.</returns>
        /// <param name="originLng">Origin lng.</param>
        /// <param name="originLat">Origin lat.</param>
        /// <param name="soriginLng">Sorigin lng.</param>
        /// <param name="soriginLat">Sorigin lat.</param>
        private async Task<double> GetDistance(double originLng, double originLat, double soriginLng, double soriginLat)
        {
            var tUrl = $"{_aMapConfig.ApiUrl}/v4/direction/bicycling?origin={originLng},{originLat}&destination={soriginLng},{soriginLat}&key={_aMapConfig.ApiKey}";
            using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, tUrl))
            {
                var client = HttpClientFactory.CreateClient("");
                using (var response = await client.SendAsync(requestMessage).ConfigureAwait(false))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                        var json = JsonConvert.DeserializeObject<JObject>(result);
                        if (json["errcode"].ToString() == "0")
                        {
                            string distance = json["data"]["paths"][0]["distance"].ToString();
                            return distance.ToDouble(0);
                        }
                    }
                }
            }

            return 0;
        }
    }
}
